package com.chuanyun.wechatcheckin.service;

import com.chuanyun.wechatcheckin.model.VacationQuotaRequest;
import com.chuanyun.wechatcheckin.model.VacationQuotaUpdateResponse;
import com.chuanyun.wechatcheckin.model.wechat.WechatTokenResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * 企业微信假期管理服务类
 * 用于修改成员假期余额
 */
@Service
public class VacationManagementService {

    private static final Logger logger = LoggerFactory.getLogger(VacationManagementService.class);
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${wechat.corpId}")
    private String corpId;

    @Value("${wechat.checkinSecret}")
    private String checkinSecret;

    /**
     * 获取假期应用访问令牌
     * 使用打卡应用的secret来获取access_token
     * 
     * @return access_token
     * @throws Exception 获取失败时抛出异常
     */
    public String getVacationAccessToken() throws Exception {
        String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", 
                                 corpId, checkinSecret);
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            
            return httpClient.execute(httpGet, response -> {
                String responseBody = EntityUtils.toString(response.getEntity());
                logger.info("获取假期应用access_token响应: {}", responseBody);
                
                WechatTokenResponse tokenResponse = objectMapper.readValue(responseBody, WechatTokenResponse.class);
                
                if (tokenResponse.getErrCode() != 0) {
                    throw new RuntimeException("获取假期应用access_token失败: " + tokenResponse.getErrMsg());
                }
                
                return tokenResponse.getAccessToken();
            });
        }
    }

    /**
     * 修改成员假期余额
     * 
     * @param request 修改假期余额请求参数
     * @return 修改结果响应
     * @throws Exception 修改失败时抛出异常
     */
    public VacationQuotaUpdateResponse updateUserVacationQuota(VacationQuotaRequest request) throws Exception {
        String accessToken = getVacationAccessToken();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/oa/vacation/setoneuserquota?access_token=" + accessToken;
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            
            // 设置请求体
            String jsonBody = objectMapper.writeValueAsString(request);
            httpPost.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON));
            
            logger.info("修改成员假期余额请求: URL={}, Body={}", url, jsonBody);
            
            return httpClient.execute(httpPost, response -> {
                String responseBody = EntityUtils.toString(response.getEntity());
                logger.info("修改成员假期余额响应: {}", responseBody);
                
                return objectMapper.readValue(responseBody, VacationQuotaUpdateResponse.class);
            });
        }
    }

    /**
     * 设置成员按天请假余额
     * 
     * @param userId 用户ID
     * @param vacationId 假期ID
     * @param days 假期天数
     * @param remarks 修改备注
     * @return 修改结果响应
     * @throws Exception 修改失败时抛出异常
     */
    public VacationQuotaUpdateResponse setUserVacationQuotaByDays(String userId, int vacationId, 
                                                                 double days, String remarks) throws Exception {
        // 按天请假：天数转换为秒（1天 = 86400秒）
        long leftDuration = Math.round(days * 86400);
        
        VacationQuotaRequest request = new VacationQuotaRequest();
        request.setUserid(userId);
        request.setVacation_id(vacationId);
        request.setLeftduration(leftDuration);
        request.setTime_attr(0); // 0 - 按天请假
        request.setRemarks(remarks);
        
        return updateUserVacationQuota(request);
    }

    /**
     * 设置成员按小时请假余额
     * 
     * @param userId 用户ID
     * @param vacationId 假期ID
     * @param hours 假期小时数
     * @param remarks 修改备注
     * @return 修改结果响应
     * @throws Exception 修改失败时抛出异常
     */
    public VacationQuotaUpdateResponse setUserVacationQuotaByHours(String userId, int vacationId, 
                                                                  double hours, String remarks) throws Exception {
        // 按小时请假：小时数转换为秒（1小时 = 3600秒）
        long leftDuration = Math.round(hours * 3600);
        
        VacationQuotaRequest request = new VacationQuotaRequest();
        request.setUserid(userId);
        request.setVacation_id(vacationId);
        request.setLeftduration(leftDuration);
        request.setTime_attr(1); // 1 - 按小时请假
        request.setRemarks(remarks);
        
        return updateUserVacationQuota(request);
    }

    /**
     * 秒转换为天数
     * 
     * @param seconds 秒数
     * @return 天数
     */
    public static double secondsToDays(long seconds) {
        return seconds / 86400.0;
    }

    /**
     * 秒转换为小时数
     * 
     * @param seconds 秒数
     * @return 小时数
     */
    public static double secondsToHours(long seconds) {
        return seconds / 3600.0;
    }

    /**
     * 天数转换为秒
     * 
     * @param days 天数
     * @return 秒数
     */
    public static long daysToSeconds(double days) {
        return Math.round(days * 86400);
    }

    /**
     * 小时数转换为秒
     * 
     * @param hours 小时数
     * @return 秒数
     */
    public static long hoursToSeconds(double hours) {
        return Math.round(hours * 3600);
    }
}